// EX/MEM

// Naming convention for wires into and out
// of this register should be [wirename]2

// In/Out Parameters with # of bits:
//    RegWrite = 1
//    RegWriteSrc = 2
//    MemWrite = 1
//    Jump = 2
//    Branch = 1
//    Zero = 1
//    ALU = 32
//    AdderB = 32
//    BusB = 32
//    Rw = 5

module Execute_Mem(CLK,
                   RegWriteIn,
                   RegWriteOut,
                   RegWriteSrcIn,
                   RegWriteSrcOut,
                   MemReadIn,
                   MemReadOut,
                   MemWriteIn,
                   MemWriteOut,
                   JumpIn,
                   JumpOut,
                   BranchIn,
                   BranchOut,
                   ZeroIn,
                   ZeroOut, 
                   ALUIn,
                   ALUOut,
                   AdderAIn,
                   AdderAOut,
                   JumpAddrIn,
                   JumpAddrOut,
                   AdderBIn,
                   AdderBOut,
                   BusAIn,
                   BusAOut,
                   BusBIn,
                   BusBOut,
                   RwIn,
                   RwOut,
                   Flush);

  input CLK,Flush;
  input RegWriteIn, MemReadIn, MemWriteIn, ZeroIn;
  input [1:0]RegWriteSrcIn, BranchIn, JumpIn;
  input [31:0]ALUIn, AdderAIn, JumpAddrIn, AdderBIn, BusAIn, BusBIn;
  input [4:0]RwIn;

  output RegWriteOut, MemReadOut, MemWriteOut, ZeroOut;
  output [1:0]RegWriteSrcOut, BranchOut, JumpOut;
  output [31:0]ALUOut, AdderAOut, JumpAddrOut, AdderBOut, BusAOut, BusBOut;
  output [4:0]RwOut;

  reg RegWriteOut, MemReadOut, MemWriteOut, ZeroOut;
  reg [1:0]RegWriteSrcOut, BranchOut, JumpOut;
  reg [31:0]ALUOut, AdderAOut, JumpAddrOut, AdderBOut, BusAOut, BusBOut;
  reg [4:0]RwOut;

  always @(negedge CLK)
    if(Flush)
      begin
        RegWriteOut <= 0;
        RegWriteSrcOut <= 0;
        MemReadOut <= 0;
        MemWriteOut <= 0;
        JumpOut <= 0;
        BranchOut <= 0;
        RwOut <= 0;
        $display($time, "  \n\n\nEX/MEM Flushed.\n\n");
      end
    else if(JumpIn === 2'bxx || BranchIn === 2'bxx)
      begin
        JumpOut <= 0;
        BranchOut <= 0;
      end
    else
      begin
        RegWriteOut <= RegWriteIn;
        RegWriteSrcOut <= RegWriteSrcIn;
        MemReadOut <= MemReadIn;
        MemWriteOut <= MemWriteIn;
        JumpOut <= JumpIn;
        BranchOut <= BranchIn;
        ZeroOut <= ZeroIn;
        ALUOut <= ALUIn;
        AdderAOut <= AdderAIn;
        JumpAddrOut<=JumpAddrIn;
        AdderBOut <= AdderBIn;
        BusAOut <= BusAIn;
        BusBOut <= BusBIn;
        RwOut <= RwIn;
      end
endmodule
